package com.yunfeisoft.common.base;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

@Transactional
public class BaseServiceImpl<T extends BaseModel, PK extends Serializable, Dao extends BaseDao<T, PK>> implements BaseService<T, PK>, ApplicationContextAware {

    protected static final Logger log = LoggerFactory.getLogger(BaseServiceImpl.class);

    private Dao dao;
    protected ApplicationContext context;

    protected Dao getDao() {
        if (dao != null) {
            return dao;
        }
        init();
        return dao;
    }

    @SuppressWarnings("unchecked")
    @PostConstruct
    public void init() {
        Type type = this.getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            Class<Dao> daoClass = (Class<Dao>) ((ParameterizedType) type).getActualTypeArguments()[2];
            dao = context.getBean(daoClass);
        } else {
            throw new RuntimeException("SubClass must give the ActualTypeArguments");
        }
    }

    @Override
    public int save(T t) {
        return dao.insert(t);
    }

    @Override
    public int batchSave(List<T> list) {
        return dao.batchInsert(list);
    }

    @Override
    public int modify(T t) {
        return dao.update(t);
    }

    @Override
    public int modifyForce(T t) {
        return dao.updateForce(t);
    }

    @Override
    public int remove(PK id) {
        return dao.delete(id);
    }

    @Override
    public int remove(PK[] ids) {
        return dao.delete(ids);
    }

	/*@DataSourceChange(slave = true)
	@Override
	public List<T> queryList(QueryCondition qc) {
		return dao.query(qc);
	}*/

	/*@DataSourceChange(slave = true)
	@Override
	public Page<T> queryPage(QueryCondition qc) {
		return dao.queryPage(qc);
	}*/

	/*@DataSourceChange(slave = true)
	@Override
	public int count(QueryCondition qc) {
		return dao.count(qc);
	}*/

    @Override
    public T load(PK id) {
        return dao.load(id);
    }

	/*@DataSourceChange(slave = false)
	@Override
	public int deleteByCondition(QueryCondition qc) {
		return dao.deleteByCondition(qc);
	}*/

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
}
